use crate::mimalloc::{types::*,internal::*};
#[repr(C)]
pub struct MiOsMemConfig {
    pub page_size: usize,
    pub large_page_size: usize,
    pub allocation_granularity: usize,
    pub has_overcommit: bool,
    pub can_partially_free: bool,
    pub has_virtual_reserve: bool,
}

static mut MI_OS_MEM_CONFIG: MiOsMemConfig = MiOsMemConfig {
    page_size: 4096,
    large_page_size: 0,
    allocation_granularity: 4096,
    has_overcommit: true,
    can_partially_free: false,
    has_virtual_reserve: true,
};

pub fn mi_os_has_overcommit() -> bool {
    unsafe { MI_OS_MEM_CONFIG.has_overcommit }
}

pub fn mi_os_has_virtual_reserve() -> bool {
    unsafe { MI_OS_MEM_CONFIG.has_virtual_reserve }
}

pub fn mi_os_page_size() -> usize {
    unsafe { MI_OS_MEM_CONFIG.page_size }
}

pub fn mi_os_large_page_size() -> usize {
    unsafe {
        if MI_OS_MEM_CONFIG.large_page_size != 0 {
            MI_OS_MEM_CONFIG.large_page_size
        } else {
            mi_os_page_size()
        }
    }
}

pub fn mi_os_use_large_page(size: usize, alignment: usize) -> bool {
    unsafe {
        if MI_OS_MEM_CONFIG.large_page_size == 0 || !mi_option_is_enabled(mi_option_allow_large_os_pages) {
            return false;
        }
        (size % MI_OS_MEM_CONFIG.large_page_size == 0) && (alignment % MI_OS_MEM_CONFIG.large_page_size == 0)
    }
}

pub fn mi_os_good_alloc_size(size: usize) -> usize {
    let align_size: usize;

    if size < 512 * MI_KiB as usize {
        align_size = mi_os_page_size();
    } else if size < 2 * MI_MiB  as usize{
        align_size = 64 * MI_KiB as usize;
    } else if size < 8 * MI_MiB  as usize {
        align_size = 256 * MI_KiB as usize;
    } else if size < 32 * MI_MiB as usize {
        align_size = 1 * MI_MiB as usize;
    } else {
        align_size = 4 * MI_MiB as usize;
    }

    if size >= (std::usize::MAX - align_size) {
        return size; // possible overflow?
    }

    mi_align_up(size, align_size)
}

pub fn mi_os_init() {
    unsafe {
        mi_prim_mem_init(&mut MI_OS_MEM_CONFIG);
    }
}
